package
{
	import Components.MovementComponent;
	
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.utils.Timer;

	public class Attacker implements IAttackable
	{
		public var health:Number = 10;
		public var attackRange:Number = .5;
		public var attackSpeed:Number = 1;
		public var attackStrength:Number = 1;
		public var displayContainer:DisplayObjectContainer;
		public var movementComponent:MovementComponent = new MovementComponent;
		public var display:Sprite = new Sprite();
		public var homeBaseToAttack:HomeBase;
		
		private var m_isAttacking:Boolean = false;
		private var m_attacksCreated:Vector.<Attack> = new Vector.<Attack>;
		private var m_attackTimer:Timer = new Timer(0);
		
		private var m_currentTarget:IAttackable;
		public var homeBaseDestructCallback:Function;
		
		public function Attacker()
		{
			var bg:Sprite = VTUtil.getRectOutline(20,20,0xff0000,2);
			bg.x = -bg.width/2;
			bg.y = -bg.height/2;
			display.addChild(bg);	
			
			m_attackTimer.addEventListener(TimerEvent.TIMER, onAttackTick);
		}
		
		private function getEnemyUnitsInRange():Vector.<IAttackable>{
			var range:Number;
			var attackableUnits:Vector.<IAttackable> = new Vector.<IAttackable>;
			for(var i:int=0, l:int=homeBaseToAttack.attackers.length; i<l ; i++){
				range = getLocation().subtract(homeBaseToAttack.attackers[i].getLocation()).length;
				if(range <= this.attackRange){
					attackableUnits.push(homeBaseToAttack.attackers[i]);	
				}
			}
			
			range = getLocation().subtract(homeBaseToAttack.getLocation()).length;
			if(range <= this.attackRange){
				attackableUnits.push(homeBaseToAttack);
			}
			
			return attackableUnits;
		}
		
		public function update(delta:int):void{
			movementComponent.update(delta);
			
			var enemyUnits:Vector.<IAttackable> = getEnemyUnitsInRange();
			if(enemyUnits.length){
				m_currentTarget = enemyUnits[0];
				if(!m_isAttacking){
					startAttack();
				}
				movementComponent.stop();
			} else {
				stopAttack();
				movementComponent.destination = homeBaseToAttack.movementComponent.location.clone();
			}
			
			for(var i:int=0, l:int=m_attacksCreated.length; i<l ; i++){
				m_attacksCreated[i].update(delta);
			}
			
			display.x = movementComponent.location.x * rts1.RATIO.x;
			display.y = movementComponent.location.y * rts1.RATIO.y;			
		}
		
		
		public function getLocation():Point{
			return movementComponent.location;
		}
		public function inflictDamage(amount:Number):void{
			this.health -= amount;
			if(this.health <= 0){
				homeBaseDestructCallback(this);
			}
		}
		public function getHealth():Number{
			return this.health;
		}
		
		private function onAttackTick(te:TimerEvent):void{
			var attack:Attack = new Attack();
			attack.damage = this.attackStrength;
			attack.target = m_currentTarget;
			attack.movementComponent.location = this.movementComponent.location.clone();
			attack.destructCallback = this.onAttackDestruction;
			this.displayContainer.addChild(attack.display);
			
			m_attacksCreated.push(attack);
		}
		
		private function onAttackDestruction(attack:Attack):void{
			attack.display.visible = false;
			attack.display.parent.removeChild(attack.display);
			m_attacksCreated.splice(m_attacksCreated.indexOf(attack),1);
		}
		
		private function startAttack():void{
			m_isAttacking = true;
			m_attackTimer.delay = 1000 / this.attackSpeed;
			m_attackTimer.start();
		}
		
		private function stopAttack():void{
			m_isAttacking = false;
			m_attackTimer.stop();
		}
	}
}